package cn.zhentao.service.impl;

import cn.zhentao.book.pojo.TBook;
import cn.zhentao.borrow.dto.BorrowDto;
import cn.zhentao.borrow.dto.BorrowShow;
import cn.zhentao.borrow.dto.Sys_BrowListDto;
import cn.zhentao.borrow.param.BroCountParam;
import cn.zhentao.common.Result;
import cn.zhentao.service.TBookService;
import cn.zhentao.service.TUserService;
import cn.zhentao.user.pojo.TUser;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zhentao.borrow.pojo.TBorrowing;
import cn.zhentao.service.TBorrowingService;
import cn.zhentao.mapper.TBorrowingMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
* @author EWEWW
* @description 针对表【t_borrowing】的数据库操作Service实现
* @createDate 2024-07-01 10:58:15
*/
@Service
public class TBorrowingServiceImpl extends ServiceImpl<TBorrowingMapper, TBorrowing>
    implements TBorrowingService{
    @Autowired
    private TUserService tUserService;
    @Autowired
    private TBookService tBookService;
    @Autowired
    private TBorrowingMapper borrowingMapper;
    //借阅图书
    @Override
    public Result borrow_book(BorrowDto dto) {
        if(dto.getUid() == null || dto.getBid() == null || dto.getNum()==null){
            return Result.ERROR("参数不能为空");
        }
        //先判断用户是否已经办卡了
        TUser user = tUserService.getById(dto.getUid());
        if(user != null){
            if(user.getCarId() == null || user.getIdcard() == null){
                return Result.ERROR("请先完善个人信息");
            }
        }
        //判断用户是否有过期未归还的图书   现根据用户id查询订单表
        List<TBorrowing> tBorrowings = borrowingMapper.selectList(Wrappers.<TBorrowing>lambdaQuery().eq(TBorrowing::getUserId, dto.getUid()));
        LocalDateTime dateTime1 = LocalDateTime.now(); // 当前时间
       if(tBorrowings.size()>0){  //大于0，说明就是有借书的存在
           for (TBorrowing tBorrowing : tBorrowings) {
               //然当前时间去比较归还时间    当前时间是否大于归还时间，如果大于说明存在未归还
               if(tBorrowing.getStatus() == 0){
                   if(dateTime1.isAfter(tBorrowing.getReturnTime()) ){  //当前时间如果在归还时间之后  并且状态等于未归还状态
                       return Result.ERROR("亲，您好请先将超时的书进行归还");
                   }
               }
           }
       }
      //判断数据库里的图书数量是否足够，然后在判断用户次数是否够用
        //判断用户剩余次数是否足够借阅的次数
        if(user.getOrderNum() == null ||user.getOrderNum()<dto.getNum()){
         return Result.ERROR("亲，您的借阅次数已不足！");
        }
        //押金至少要有50元
        if(user.getBalance()<50){
            return Result.ERROR("押金不足，请充值");
        }


        //根据图书id查询用户要借阅的图书
        TBook book = tBookService.getById(dto.getBid());
        //判断该书是否上架
        if(book.getStatus() != 0){
            return Result.ERROR("抱歉，该书已下架或不租借哦");
        }
        //判断数量
        if(dto.getNum()>book.getNum()){
            return Result.ERROR("抱歉，该书已被借完！");
        }
        //根据用户id 和 书的id 判断订单表里是否已经存在   存在就返回告诉用户书已存在  否则添加
        List<TBorrowing> tBorrowing = borrowingMapper.selectList(Wrappers.<TBorrowing>lambdaQuery().
             eq(TBorrowing::getUserId, dto.getUid()).
             eq(TBorrowing::getBookId, dto.getBid()));
        LocalDateTime return_time = dateTime1.plusDays(30);//规划30天后归还时间 (根据当前时间+30天后)
        if(tBorrowing.size() == 0){
            //修改用户个人次数
            user.setOrderNum(user.getOrderNum()-dto.getNum());//原本次数减去所选择的次数
            tUserService.updateById(user);  //提交数据库
            //修改库存量
            book.setNum(book.getNum()-dto.getNum());//原本的库存量书减去借出去书的次数
            tBookService.updateById(book);
            //添加到订单表
            TBorrowing borrowing = new TBorrowing();
            borrowing.setBookId(dto.getBid());  //书的id
            borrowing.setUserId(dto.getUid());  //用户id
            borrowing.setNum(dto.getNum());   //借的数量
            borrowing.setCard(user.getCarId());   //卡的类型
            borrowing.setDay(30);  //默认天数
            borrowing.setReturnTime(return_time);
            borrowingMapper.insert(borrowing);
            TUser newuser = tUserService.getById(dto.getUid()); //同步将用户最新数据展示给前端
            return Result.OK(newuser,"借阅成功！");
        }
        for (TBorrowing borrowing : tBorrowing) {
            if(borrowing.getStatus() == 0 || borrowing.getStatus() == 2){  //有借阅约的
                return Result.ERROR("您已借阅过此书，请再换一本吧!");
            }
            if( borrowing.getStatus() == 3){
                borrowingMapper.delete(Wrappers.<TBorrowing>lambdaQuery().
                        eq(TBorrowing::getStatus,1).
                        eq(TBorrowing::getId,borrowing.getId()));
                /*处理借阅表*/
                borrowing.setStatus(0);//将它的状态修改为借阅中
                borrowing.setCreateTime(new Date());//创建时间重新规划
                borrowing.setReturnTime(return_time);//归还时间重新定义
                borrowingMapper.updateById(borrowing);//提交数据库
                /* 处理用户表*/
                user.setOrderNum(user.getOrderNum()-dto.getNum());//原本次数减去所选择的次数
                tUserService.updateById(user);  //提交数据库
                /*处理图书表中的【库存量】*/
                book.setNum(book.getNum()-dto.getNum());//原本的库存量书减去借出去书的次数
                tBookService.updateById(book);//提交数据库
                /*同步将用户最新数据展示给前端*/
                TUser newuser = tUserService.getById(dto.getUid());
                return Result.OK(newuser,"您预约的书，借阅成功哦！");
            }
        }
        for (TBorrowing borrowing : tBorrowing) {
            if(borrowing.getStatus() == 1){
                /*处理借阅表*/
                borrowing.setStatus(0);//将它的状态修改为借阅中
                borrowing.setCreateTime(new Date());//创建时间重新规划
                borrowing.setReturnTime(return_time);//归还时间重新定义
                borrowingMapper.updateById(borrowing);//提交数据库
                /* 处理用户表*/
                user.setOrderNum(user.getOrderNum()-dto.getNum());//原本次数减去所选择的次数
                tUserService.updateById(user);  //提交数据库
                /*处理图书表中的【库存量】*/
                book.setNum(book.getNum()-dto.getNum());//原本的库存量书减去借出去书的次数
                tBookService.updateById(book);//提交数据库
                /*同步将用户最新数据展示给前端*/
                TUser newuser = tUserService.getById(dto.getUid()); //同步将用户最新数据展示给前端
                return Result.OK(newuser,"借阅成功！");
            }
        }
        return Result.ERROR("您已借阅过此书，请再换一本吧!");
    }

   //图书查询
    @Override
    public Result selusrbrolist(BorrowShow show) {
      List<TBorrowing> borrowings = borrowingMapper.selusrbrolist(show);
        return Result.OK(borrowings);
    }
    //归还图书
    @Override
    public Result book_back(BorrowDto dto) {
        //判断参数是否为空
        if(dto.getUid() == null || dto.getBid() == null){
            return Result.ERROR("参数不能为空");
        }

        //根据用户id和图书id查询
        TBorrowing tBorrowing = borrowingMapper.selectOne(Wrappers.<TBorrowing>lambdaQuery().
                eq(TBorrowing::getUserId, dto.getUid()).
                eq(TBorrowing::getBookId, dto.getBid()).
                eq(TBorrowing::getStatus,0));//改了个0
        if(tBorrowing == null ){
            return Result.ERROR("您没有这条借阅记录哦!");
        }
        //判断借阅的状态 0-借阅中  1-归还  2-续约中   3-预约
        if(tBorrowing.getStatus() ==1 || tBorrowing.getStatus() ==3){
            //该书已经被归还或者正在预约中，反正就是没有借阅这本书
            return Result.ERROR("您还没有借阅此书哦---已经归还或者预约中");
        }
        TBook book = tBookService.getById(dto.getBid());//查询图书
        TUser user = tUserService.getById(dto.getUid());
        //判断  归还的时间 和当前时间  比较   超过扣押金   不超过   不扣
        LocalDateTime now = LocalDateTime.now(); //当前时间
        if(now.isAfter(tBorrowing.getReturnTime()) || now.isEqual(tBorrowing.getReturnTime())){  //规定时间内归还的
            //计算出天数       1天/0.2
            long day = ChronoUnit.DAYS.between(tBorrowing.getReturnTime(),now);
            //计算价格
            double v = day * 0.2;
            double blance = Math.rint(v);//四舍五入计算出价格
            if(user.getBalance()<blance){
                //列入失信名单中
            }
            /*减去所需要支付的违约金以及用户次数归还【用户表】*/
            user.setBalance(user.getBalance()-blance);//原本的钱数减去违约金
            user.setOrderNum(user.getOrderNum()+1);//回归原本次数
            tUserService.updateById(user);
            /*借阅表图书归还【借阅表】*/
            tBorrowing.setNum(0);//借阅表图书数量清空
            tBorrowing.setDay(0);//借阅的天数清空
            tBorrowing.setStatus(1);//改为归还状态
            borrowingMapper.updateById(tBorrowing);//借阅表提交到数据库
            /*将图书的数量回归【图书表】*/
            book.setNum(book.getNum()+1);//在原来的数量基础上加1
            tBookService.updateById(book);//图书提交到数据库

            TUser newuser = tUserService.getById(user.getId());//查询出新的用户数据返回给前端
            return Result.OK(newuser,"超时归还成功,系统已扣除一定费用");
        }
        /*修改借阅表信息*/
        tBorrowing.setNum(0);//借阅表图书数量清空
        tBorrowing.setDay(0);//借阅的天数清空
        tBorrowing.setStatus(1);//改为归还状态
        borrowingMapper.updateById(tBorrowing);//借阅表提交到数据库
        /*将图书的数量回归*/
        book.setNum(book.getNum()+1);//在原来的数量基础上加1
        tBookService.updateById(book);//图书提交到数据库
        /*用户次数归还【用户表】*/
        user.setOrderNum(user.getOrderNum()+1);//回归原本次数
        tUserService.updateById(user);
        TUser newuser = tUserService.getById(user.getId());//查询出新的用户数据返回给前端
        return Result.OK(newuser,"归还成功");
    }
    //统计图分析方法
    @Override
    public List<BroCountParam> brocountlist(Integer id) {
        return borrowingMapper.countList(id);
    }

    //用户预约
    @Override
    public Result yuyue(BorrowDto dto) {
        //先判断参数是否为空
        if(dto.getUid() == null || dto.getBid() == null){
            return Result.ERROR("参数不能为空");
        }
        TUser user = tUserService.getById(dto.getUid());
        //判断是否有该用户
//        if(user == null){return Result.ERROR("请先注册");}
        //先判断用户是否已经办卡了
        if(user != null){
            if(user.getCarId() == null || user.getIdcard() == null){
                return Result.ERROR("请先完善个人信息");
            }
        }
        TBook book = tBookService.getById(dto.getBid());
        //判断有无此书
        if(book == null){
            return Result.ERROR("还没有该图书哦");
        }
        //判断该书是否可以借阅
        if(book.getStatus() !=0 ){
            return Result.ERROR("抱歉，该书已下架或不租借哦");
        }
        //判断该书数量   有数量不能预约     以及判断预约的人是否已经借阅的书也不能预约
        if(book.getNum()>0){
            return Result.ERROR("还有库存量，赶快借阅吧");
        }
        TBorrowing Borrowing = borrowingMapper.selectOne(Wrappers.<TBorrowing>lambdaQuery().
                eq(TBorrowing::getUserId, dto.getUid()).
                eq(TBorrowing::getBookId, dto.getBid()).
                eq(TBorrowing::getStatus,0));
        if(Borrowing == null){

        }else{
            return Result.ERROR("此书已被你借阅或者续约中，不能预约哦");
        }
        //0-借阅中  1-归还  2-续约中   3-预约
        //根据用户id 和 图书id 查询用户借阅表  是否有该借阅记录 并且 借阅状态不能等于0和2  如果有  提示用户  您已借阅此书，不能预约哦
        TBorrowing tBorrowing = borrowingMapper.selectOne(Wrappers.<TBorrowing>lambdaQuery().
                eq(TBorrowing::getUserId, dto.getUid()).
                eq(TBorrowing::getBookId, dto.getBid()).
                eq(TBorrowing::getStatus,3));
        if(tBorrowing == null){
            TBorrowing tBorrowing1 = new TBorrowing();
            tBorrowing1.setUserId(dto.getUid());//预约的用户
            tBorrowing1.setBookId(dto.getBid());//预约的图书
            tBorrowing1.setNum(1);//预约数量
            tBorrowing1.setCard(user.getCarId());//用户预约的卡
            tBorrowing1.setStatus(3);//预约中
            borrowingMapper.insert(tBorrowing1);
            return Result.OK("预约成功");
        }
        if(tBorrowing.getStatus() == 0 || tBorrowing.getStatus()==2){
            return Result.ERROR("此书已被你借阅或者续约中，不能预约哦");
        }
        //判断用户是否已经预约此书
        if(tBorrowing.getStatus() == 3){
            return Result.ERROR("您已预约该图书哦");
        }
        //预约用户次数不用修改  书的数量不用修改   只添加借阅表数据  且状态是3  表示预约中
        TBorrowing tBorrowing1 = new TBorrowing();
        tBorrowing1.setUserId(dto.getUid());//预约的用户
        tBorrowing1.setBookId(dto.getBid());//预约的图书
        tBorrowing1.setNum(1);//预约数量
        tBorrowing1.setCard(user.getCarId());//用户预约的卡
        tBorrowing1.setStatus(3);//预约中
        borrowingMapper.insert(tBorrowing1);
        return Result.OK("预约成功");
    }
    //用户取消预约
    @Override
    public Result UnYuyue(BorrowDto dto) {
        //判断参数是否为空
        if(dto.getUid() == null || dto.getBid() == null || dto.getStatus() == null){
            return Result.ERROR("参数不能为空");
        }
        if(dto.getStatus() != 3){
            return Result.ERROR("该书不是预约状态，无法取消");
        }
        //根据 【用户id】 和 【图书id】 和 【状态】  查询
        TBorrowing tBorrowing = borrowingMapper.selectOne(Wrappers.<TBorrowing>lambdaQuery().
                eq(TBorrowing::getUserId, dto.getUid()).
                eq(TBorrowing::getBookId, dto.getBid()).
                eq(TBorrowing::getStatus, dto.getStatus()));
        if(tBorrowing == null ){
            return Result.ERROR("您没有这条预约记录哦!");
        }
        //判断借阅的状态 0-借阅中  1-归还  2-续约中   3-预约
        if(tBorrowing.getStatus() !=3 ){
            //该书已经被归还或者正在预约中，反正就是没有借阅这本书
            return Result.ERROR("您没有这条预约记录哦!---已经归还或者借阅中");
        }
        //取消预约就是把借阅表记录中  又借阅记录 且  状态  是 3  给删除掉
        borrowingMapper.deleteById(tBorrowing.getId());
        return Result.OK("取消预约成功");
    }
    //自动提醒预约的用户
    @Override
    public Result Reser_title(Integer uid) {
        //判断参数是否为空
        if(uid == null){
            return Result.ERROR("参数不能为空");
        }
        //根据用户id查询借阅表
        List<TBorrowing>  tBorrowinglist = borrowingMapper.selectList(Wrappers.<TBorrowing>lambdaQuery().
                eq(TBorrowing::getUserId, uid).
                eq(TBorrowing::getStatus,3));
        //根据用户id查询出来的借阅表
        if(tBorrowinglist.size() <=0){
            return Result.ERROR(null);
        }
        String bid ="";
         //遍历判断
        for (TBorrowing tBorrowing : tBorrowinglist) {
            if(tBorrowing.getStatus() ==3){
                bid+=tBorrowing.getBookId()+",";
            }
        }
        //自动提醒用户   判断要预约的图书库存量是否大于0  还要判断借阅表的是否有   有的话  状态是否为3
        String[] split = bid.split(",");
        if(split.length == 0){
            return Result.ERROR(null);
        }
        int i=0;
        //判断要预约的图书库存量是否大于0
        for (String s : split) {
            TBook book = tBookService.getById(Integer.valueOf(s));
            if(book == null){

            }else{
                if(book.getNum() != 0){
                   ++i;
                }
            }
        }
        if(i == 0){
            return Result.ERROR(null);
        }
        return Result.OK("您有"+i+"本预约的书，可以借阅了哦!");
    }
    //管理员端查询
    @Override
    public Page<TBorrowing> Sys_list(Sys_BrowListDto dto) {
          if(dto.getDayId() != null){  //说明管理员想查询剩余3天或一周内快要归还的用户
              // 创建一个Date对象，这里假设是当前的日期和时间
              Date currentDate = new Date();
              // 使用Calendar来操作日期
              Calendar calendar = Calendar.getInstance();
              // 设置Calendar的时间为当前时间
              calendar.setTime(currentDate);
              // 给日期加上5天
              calendar.add(Calendar.DAY_OF_MONTH, dto.getDayId());
              // 将修改后的Calendar时间转换回Date对象
              Date newDate = calendar.getTime();
              dto.setU_now(currentDate);//当前时间
              dto.setU_end(newDate);//归还时间范围
          }
        Page<TBorrowing> page = new Page<>(dto.getPagenum(), dto.getPagesize());
        Page<TBorrowing> syslist = borrowingMapper.sys_list(page,dto);
        return syslist;
    }
}




